#include "stdafx.h"

#include "MyNppToolbox.h"

#include "Scintilla.h"
#include "Notepad_plus_msgs.h"
#include "menuCmdID.h"
#include "PluginExport.h"

#include "NppWraper.h"

#include "FileWatcher.h"

//////////////////////////////////////////////////////////////////////////
// TODO : user defined function array
//
FuncItem g_FuncItemsArray[] = {
	/*
	struct FuncItem {
		TCHAR _itemName[nbChar];
		PFUNCPLUGINCMD _pFunc;
		int _cmdID;
		bool _init2Check;
		ShortcutKey* _pShKey;
	};
	*/
	/*
	{ L"Foo", Foo, 0, false, NULL },
	{ L"Bar", Bar, 0, false, NULL },

	{ NULL, NULL, 0, false, NULL },			// menu separator
	
	{ L"BlaBla", BlaBla, 0, false, NULL }
	*/
	{ L"Copy line", CopyLine, 0, false, NULL },
	{ L"Cut line", CutLine, 0, false, NULL },

	{ NULL, NULL, 0, false, NULL },			// menu separator

	{ L"Set ref number", SetRefListNumber, 0, false, NULL },
	{ L"Break at [", BreakBracket, 0, false, NULL },

	{ NULL, NULL, 0, false, NULL },			// menu separator

	{ L"Browse ABAQUS rpy file...", BrowseAbaRpyFile, 0, false, NULL },
	{ L"Stop watch", StopWatch, 0, false, NULL },
	{ L"Select previous", SelPrev , 0, false, NULL },
	{ L"Select next", SelNext , 0, false, NULL }
};

//////////////////////////////////////////////////////////////////////////
// internal global data
//
const int g_FuncItemCount = sizeof(g_FuncItemsArray)/sizeof(g_FuncItemsArray[0]);

void GetFuncItemsArray(FuncItem** ppFuncItem, int* itemCount)
{
	*ppFuncItem = g_FuncItemsArray;
	*itemCount = g_FuncItemCount;
}

NppData g_NppData;
void SetNppData(NppData notpadPlusData)
{
	g_NppData = notpadPlusData;
}

// Get global g_NppData object
NppData GetNppData()
{
	return g_NppData;
}

//////////////////////////////////////////////////////////////////////////
// initialization and uninitialization
//
void pluginInit(HANDLE hModule)
{
	// TODO : initialization code here
	//
}

void pluginCleanUp()
{
	// TODO : uninitialization code here
	//
}

//////////////////////////////////////////////////////////////////////////
// TODO : user defined function definition
//
/*
void Foo()
{
	::MessageBox(NULL,L"Foo",L"Npp message",MB_OK);
}

void Bar()
{
	::MessageBox(NULL,L"Bar",L"Npp message",MB_OK);
}

void BlaBla()
{
	::MessageBox(NULL,L"bla bla",L"Npp message",MB_OK);
}
*/

// Copy current line 
void CopyLine()
{
	CSciWindow sci(GetNppData());
	if (sci.IsSelectionEmpty())
	{
		//sci.SelectCurLine();
		sci.CopyCurrentLineContent();	// copy current line content (without the line end character)
	}
	else
	{
		sci.Copy();
	}
	//sci.CopyAllowLine();	// copy current line (with the line end character)
}

// Cut current line 
void CutLine()
{
	CSciWindow sci(GetNppData());
	if (sci.IsSelectionEmpty())
	{
		sci.SelectCurLine();
	}
	sci.Cut();
}

// Set the number of reference list 
void SetRefListNumber()
{
	CSciWindow sci(GetNppData());
	int lineCount = sci.GetLineCount();
	for (int lineNum = 0; lineNum<lineCount; ++lineNum)
	{
		ATL::CString text = sci.GetLine(lineNum);
		int pos = text.Find(L"]",0);
		if (pos<0 || pos>4)
			continue;

		int lineStart = sci.PositionFromLine(lineNum);
		sci.SetTargetStart(lineStart);
		sci.SetTargetEnd(lineStart+pos+1);
		ATL::CString strNum;
		strNum.Format(L"[%d]",lineNum+1);
		sci.ReplaceTarget(strNum);
	}
}

//
void BreakBracket()
{
	CSciWindow sci(GetNppData());
	int flags = sci.GetSearchFlags();
	sci.SetSearchFlags(SCFIND_MATCHCASE);

	int targetStart = 0;
	int targetEnd = sci.GetDocumentEndPosition();
	while (targetStart<targetEnd)
	{
		sci.SetTargetStart(targetStart);
		sci.SetTargetEnd(targetEnd);

		int pos = sci.SearchInTarget(L"[");
		if (pos<0)
		{
			return;
		}

		int lineNum = sci.LineFromPosition(pos);
		int lineStart = sci.PositionFromLine(lineNum);
		if (pos<=lineStart)
		{
			targetStart = pos+1;
			continue;
		}

		sci.InsertText(pos,L"\r\n");

		targetStart = pos+1;
		targetEnd = sci.GetDocumentEndPosition();
	}

	sci.SetSearchFlags(flags);
}

//////////////////////////////////////////////////////////////////////////
//
CNotifyWindow g_NotifyWindow;
ATL::CString g_AbaRpyFilePath = L"";
//
void BrowseAbaRpyFile()
{
	StopWatch();

	//
	CNppWindow npp(GetNppData());

	WTL::CFileDialog fd(TRUE,
		L"rpy",
		L"abaqus.rpy",
		OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST,
		L"ABAQUS rpy file\0*.rpy\0\0");
	INT_PTR res = fd.DoModal(npp.m_hWnd);
	if (res == IDCANCEL)
		return;

	g_AbaRpyFilePath = fd.m_szFileName;

	npp.DoOpen(g_AbaRpyFilePath);
	npp.SetCurrentLang(IDM_LANG_PYTHON);
	npp.EditSetReadonly();

	ATL::CString rpyFileDir = g_AbaRpyFilePath.Left(g_AbaRpyFilePath.ReverseFind('\\')+1);

	ATLASSERT(g_NotifyWindow.m_hWnd == NULL);
	g_NotifyWindow.Create(GetNppData(),rpyFileDir,L"abaqus.rpy");
}

void StopWatch()
{
	if (g_NotifyWindow.m_hWnd!=NULL && !g_NotifyWindow.IsStopped())
	{
		g_NotifyWindow.StopWatch();
		g_NotifyWindow.DestroyWindow();
	}
}

void SelPrev()
{
	if (g_NotifyWindow.m_hWnd!=NULL && !g_NotifyWindow.IsStopped())
	{
		g_NotifyWindow.PostMessage(WM_USER_SEL_PREV);
	}
}

void SelNext()
{
	if (g_NotifyWindow.m_hWnd!=NULL && !g_NotifyWindow.IsStopped())
	{
		g_NotifyWindow.PostMessage(WM_USER_SEL_NEXT);
	}
}